<route lang="json5">
{
  style: {
    navigationBarTitleText: '掌上建议新增',
  },
}
</route>
<template>
  <view class="px-2 py-4">
    <wd-message-box />
    <wd-toast />
    <wd-form ref="formRef" labelWidth="120" :model="formData" :rules="formRules">
      <wd-cell-group border>
        <view class="bg-#f5f7f9">
          <wd-card>
            <view class="">
              <!-- input 标题-->
              <wd-textarea
                label="标题"
                label-width="100px"
                prop="title"
                v-model="formData.title"
                placeholder="请输入标题"
                clearable
                auto-height
              />

              <!-- textarea 文本域 -->
              <wd-cell title="意见内容" title-width="100px" reqired></wd-cell>
              <wd-textarea
                prop="content"
                v-model="formData.content"
                placeholder="请输入意见内容(不少于20个字)"
                clearable
              />
            </view>
          </wd-card>
          <wd-card>
            <view class="">
              <!-- upload 文本/图片上传 -->
              <wd-cell title="文件上传" title-width="100px"></wd-cell>
              <view class="flex flex-justify-around">
                <view v-for="(item, index) in 3" :key="index" class="upload-wrapper">
                  <wd-upload
                    :file-list="fileList[index]"
                    :action="uploadUrl"
                    :limit="1"
                    accept="media"
                    :source-type="['camera']"
                    :show-upload-list="true"
                    :header="headerObj"
                    :formData="uploadExtraData[index]"
                    :custom-upload="true"
                    @before-upload="(e) => handleBeforeUpload(e, index)"
                    @change="(file) => handleFileChange(file, index)"
                    reupload
                    @success="(res) => handleSingleUpload(res, index)"
                    @remove="(file) => handleRemove(file.file, index)"
                  ></wd-upload>
                </view>
              </view>
            </view>
          </wd-card>
          <wd-card>
            <view class="">
              <wd-cell title="意见录音" title-width="100px" v-if="showTibetan">
                <view class="flex items-center">
                  <wd-button size="small" type="error" @click="toggleRecord">
                    {{ isRecording ? '停止录音' : '开始录音' }}
                  </wd-button>
                </view>
              </wd-cell>

              <!-- <text v-if="audioFile.name" class="ml-2 text-sm">{{ audioFile.name }}</text> -->
              <audio
                v-if="audioFile.url"
                :src="audioFile.url"
                controls
                class="ml-2"
                style="width: 180px"
              />

              <!-- datetime 时间选择器 -->
              <wd-datetime-picker
                label="提交时间"
                label-width="100px"
                prop="submittedAt"
                disabled
                v-model="formData.submittedAt"
                type="date"
                placeholder="请选择时间"
                :default-value="defaulTimetValue"
              />

              <wd-select-picker
                label="建议范围"
                label-width="100px"
                prop="groupId"
                v-model="formData.groupId"
                :columns="dicts"
                placeholder="请选择建议范围"
                type="radio"
                value-key="value"
                label-key="label"
                clearable
                filterable
                :show-confirm="false"
              />

              <wd-cell title="匿名提交" title-width="100px">
                <wd-switch
                  v-model="isAnonymous"
                  active-color="#ff0000"
                  @change="handleAnonymousChange"
                />
              </wd-cell>

              <wd-cell title="位置信息" label-width="50px">
                <view class="" v-if="formData.location">
                  {{ formData.location }}
                </view>
                <view v-if="!formData.location">
                  <wd-button size="small" type="primary" @click="getCurrentLocation">
                    重新定位
                  </wd-button>
                </view>
              </wd-cell>
            </view>
          </wd-card>
        </view>
      </wd-cell-group>
      <view class="footer" style="margin-top: 30px">
        <view class="flex flex-justify-center">
          <wd-button type="error" @click="submitForm" block custom-class="custom-shadow">
            提交
          </wd-button>
        </view>
      </view>
    </wd-form>
  </view>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import {
  IPalmAdviceVo,
  palmAdviceList,
  palmAdviceById,
  createPalmAdvice,
  updatePalmAdvice,
  deletePalmAdvice,
} from '@/api/palmAdvice'
import { getDictByType } from '@/api/dict'
// import { getAccessToken } from '@/utils/auth'
import { useMessage, useToast } from 'wot-design-uni'

import { useUserStore } from '@/store/user'
import { useTenantStore } from '@/store/tenant'

import { formatDate, parseTimeToTimestamp } from '@/utils/date'
import { showToastAsync } from '@/utils/toast'
import QQMapWX from '@/utils/qqmap-wx-jssdk'

// const QQMapWX = require('@/static/map/qqmap-wx-jssdk')
// 实例化API核心类
var qqmapsdk = new QQMapWX({
  // key: 'SE7BZ-74NYA-YIHKL-CQ6EG-FTECQ-CWFDK' // 必填
  key: 'SE7BZ-74NYA-YIHKL-CQ6EG-FTECQ-CWFDK', // 必填
})
const showTibetan = import.meta.env.VITE_SHOW_TIBETAN === 'true'

const store = useUserStore()
const tenantStore = useTenantStore()
const tenant = computed(() => tenantStore.tenantInfo)
const message = useMessage()
const toast = useToast()

const headerObj = ref({
  Authorization: 'Bearer',
})
const recorderManager = uni.getRecorderManager()
const isRecording = ref(false)
const audioFile = reactive<{ name: string; url: string }>({ name: '', url: '' })

const uploadUrl = import.meta.env.VITE_UPLOAD_BASEURL
const representativeId = ref(null) //传过来的人大代表id
const detailId = ref(null) //详情id

const isLoading = ref(false) // 避免重复请求
const isAnonymous = ref(false) // 默认匿名提交

/**日期选择器默认值 */
const defaulTimetValue = ref<number>(Date.now())

const fileList = ref<any[]>([])
// 每个上传组件的额外 data 参数（动态维护）
const uploadExtraData = ref<{ [key: number]: any }>({})
const dicts = ref<any[]>([]) //职能部门字典数据
const formRef = ref(null)
const formData = ref<Partial<IPalmAdviceVo>>({
  submitterName: store.userInfo.userName,
  submittedAt: defaulTimetValue.value,
  title: '',
  content: '',
  groupId: '',
  isAnonymous: 0,
  attachmentFiles: [],
  record: undefined,
  location: '',
  latitude: undefined,
  longitude: undefined,
})
const formRules: any = reactive({
  title: [
    {
      required: true,
      validator: (value: any) => {
        if (!value) {
          return Promise.reject(new Error(''))
        } else {
          return Promise.resolve()
        }
      },
      trigger: ['blur', 'change', 'input'],
    },
  ],
  content: [
    {
      required: true,
      validator: (value: any) => {
        if (value.length >= 20) {
          return Promise.resolve()
        } else {
          return Promise.reject(new Error(''))
        }
      },
      trigger: ['blur', 'change', 'input'],
    },
  ],
  submittedAt: [
    {
      required: true,
      validator: (value: any) => {
        if (!value) {
          return Promise.reject(new Error(''))
        } else {
          return Promise.resolve()
        }
      },
      trigger: ['blur', 'change', 'input'],
    },
  ],
  groupId: [
    {
      required: true,
      validator: (value: any) => {
        if (!value) {
          return Promise.reject(new Error(''))
        } else {
          return Promise.resolve()
        }
      },
      trigger: ['blur', 'change', 'input'],
    },
  ],
})
onLoad(async (options) => {
  console.log('✅ 页面 onLoad 执行了', options)
  formData.value.tenantId = tenant.value.tenantId
  await getDictsByType()
  console.log('字典获取到')

  representativeId.value = Number(options?.representativeId)
  detailId.value = options?.id
  console.log('获取位置')
  if (!detailId.value) {
    getCurrentLocation()
  }

  /** 获得详情 */
  if (detailId.value) {
    getDetailById()
  }

  console.log('123')
})
// 匿名切换事件
const handleAnonymousChange = (val: any) => {
  if (val.value) {
    formData.value.submitterName = '匿名'
    formData.value.isAnonymous = 1
  } else {
    formData.value.submitterName = store.userInfo.userName
    formData.value.isAnonymous = 0
  }
}
// 每次文件变更时，记录文件名
const handleFileChange = (fileInfo: any, index: number) => {
  const lastFile = fileInfo?.fileList?.[fileInfo.fileList.length - 1]
  if (lastFile?.name) {
    // 记录原始文件名（不是从上传成功返回的）
    uploadExtraData.value[index] = { name: lastFile.name }
  }
}

/** 上传文件成功后统一处理逻辑：构建文件对象 + 更新 attachmentUrlList */
const handleSingleUpload = (res: any, index: number) => {
  try {
    const parsed = JSON.parse(res.file.response)
    if (parsed.code !== 0) {
      toast.error(parsed.msg || '上传失败')
      return
    }

    const fileName = uploadExtraData.value[index]?.name || '未命名文件'
    const file = [
      {
        name: fileName, // ✅ 使用上传时记录的文件名
        url: parsed?.url || parsed.data,
        status: 'done',
      },
    ]

    fileList.value[index] = file
    console.log('fileList.value', fileList.value)

    // ✅ 关键修改：将二维数组扁平化，再映射文件对象
    formData.value.attachmentFiles = fileList.value
      .flat() // 二维转一维（如[[file1],[file2]] → [file1, file2]）
      .filter(Boolean) // 过滤空文件（可选）
      .map((fileObj) => ({
        // fileObj是文件对象（如file1）
        name: fileObj.name,
        url: fileObj.url,
      }))
    console.log('formData.value.attachmentFiles', formData.value.attachmentFiles)
    toast.success('上传成功')
  } catch (e) {
    toast.error('上传失败')
  }
}
/** 处理文件删除 */
const handleRemove = (file: any, index: number) => {
  try {
    // 过滤逻辑（保持原代码）
    const filteredFiles = fileList.value[index].filter(
      (f: any) => f.url !== file.url, // 关键：用url唯一标识文件
    )
    fileList.value[index] = filteredFiles // 更新子数组
    // 同步更新formData（保持原代码）
    formData.value.attachmentFiles = fileList.value
      .flat()
      .filter(Boolean)
      .map((f: any) => ({ name: f.name, url: f.url }))
    console.log('formData.value.attachmentFiles', formData.value.attachmentFiles)

    toast.success('文件删除成功')
  } catch (e) {
    console.error('文件删除失败:', e)
    toast.error('文件删除失败')
  }
}

/** 获取字典数据 */
const getDictsByType = async () => {
  const res: any = await getDictByType({ dictType: 'type_of_recommendation ' })
  if (res.code === 0) {
    dicts.value = res.data?.map((item) => ({
      label: item.dictLabel,
      value: item.dictValue,
    }))
  }
}
/** 获取页面详情 */
const getDetailById = async () => {
  try {
    const res = await palmAdviceById(detailId.value)
    if (res.code === 0) {
      formData.value = res.data || {}
      if (formData.value.content) {
        formData.value.content = formData.value.content.replace(/<[^>]+>/g, '')
      }
      if (formData.value.isAnonymous) {
        isAnonymous.value = formData.value.isAnonymous === 1
      }
      // 图片处理 ✅
      if (formData.value.attachmentFiles) {
        formData.value.attachmentFiles.forEach((file, index) => {
          if (index < 3) {
            fileList.value[index] = [
              {
                name: file.name,
                url: file.url,
                status: 'done',
              },
            ]
          }
        })
      }
      console.log('fileList.value', fileList.value)
      formData.value.groupId = String(formData.value.groupId ?? '')
      formData.value.submittedAt = parseTimeToTimestamp(formData.value.submittedAt)
      console.log('detailData.value', formData.value)
    }
  } catch (error) {
    console.error(error)
  } finally {
    isLoading.value = false
  }
}

/** 提交表单 */
const submitForm = async () => {
  try {
    // 校验表单
    if (!formRef.value) return
    // 校验表单
    const { valid, errors } = await formRef.value.validate()
    if (!valid) {
      console.log('表单校验未通过:', errors)
      // 根据字段名自定义提示
      if (errors.some((e) => e.prop === 'title')) {
        await showToastAsync('标题不能为空', 1500, 'none')
      } else if (errors.some((e) => e.prop === 'content' && !formData.value.content)) {
        await showToastAsync('意见不能为空', 1500, 'none')
      } else if (errors.some((e) => e.prop === 'content' && formData.value.content.length < 20)) {
        await showToastAsync('意见内容不少于20个字', 1500, 'none')
      } else if (errors.some((e) => e.prop === 'groupId')) {
        await showToastAsync('建议范围不能为空', 1500, 'none')
      }
      return // ✅ 校验失败，终止后续代码
    }
    if (!detailId.value) formData.value.representativeId = representativeId.value
    uni.showLoading({
      // 正确：用${}包裹三元表达式，动态切换标题
      title: `${detailId.value ? '编辑中...' : '新增中...'}`,
      mask: true,
    })
    if (!formData.value.location.includes(tenant.value.remark)) {
      await showToastAsync(`当前位置不在${tenant.value.remark}景区内请重试`, 1500, 'none')
      return
    }
    if (detailId.value) {
      const res = await updatePalmAdvice(formData.value)
      if (res.code === 0) {
        // uni.showToast({ title: '编辑成功' });
        await showToastAsync('编辑成功') // ✅ 等待提示显示完再跳转
        await uni.showModal({
          title: '感谢您的建议',
          content:
            '您好！感谢您为和美共和文旅事业提出的宝贵建议。我们将根据您的宝贵建议提升我们的服务品质。',
          showCancel: false,
          confirmText: '知道了',
        })
      }
    } else {
      const res = await createPalmAdvice(formData.value)
      if (res.code === 0) {
        // uni.showToast({ title: '新增成功' });
        await showToastAsync('新增成功')
        await uni.showModal({
          title: '感谢您的建议',
          content:
            '您好！感谢您为和美共和文旅事业提出的宝贵建议。我们将根据您的宝贵建议提升我们的服务品质。',
          showCancel: false,
          confirmText: '知道了',
        })
      }
    }
    // setTimeout(() => {
    //   // 成功后跳转
    //   uni.switchTab({ url: '/pages/palmAdvice/index' })
    // }, 1500)
    uni.switchTab({ url: '/pages/palmAdvice/index' })
  } catch (error) {
    console.error('表单提交失败:', error)
    toast.error('提交失败，请稍后再试')
  } finally {
    // ✅ 第五步：无论成功/失败，关闭加载提示（必须执行）
    uni.hideLoading()
  }
}
//选择位置
const chooseLocation = () => {
  uni.chooseLocation({
    // ✅ 把坐标作为参数传进去
    latitude: formData.value.latitude ?? undefined,
    longitude: formData.value.longitude ?? undefined,
    success: function (res) {
      formData.value.location = res.name
      formData.value.detailedLocation = res.address
      formData.value.latitude = res.latitude
      formData.value.longitude = res.longitude
      console.log('formData.value', formData.value)
    },
  })
}
//获取当前位置
// const getCurrentLocation = () => {
//   console.log('进来了没，获取当前位置');

//   // 封装递归尝试定位的函数
//   const tryGetLocation = () => {
//     uni.getLocation({
//       type: 'gcj02',
//       success(res) {
//         console.log('定位成功：', res)

//         // 逆地址解析（腾讯地图）
//         qqmapsdk.reverseGeocoder({
//           location: {
//             latitude: res.latitude,
//             longitude: res.longitude
//           },
//           success(res) {
//             console.log('res经纬度反编码', res);
//             formData.value.latitude = res.result.location.lat
//             formData.value.longitude = res.result.location.lng
//             formData.value.detailedLocation = res.result.address
//             formData.value.location = res.result.formatted_addresses?.recommend || res.result.address
//             console.log('formData.value', formData.value);
//           },
//           fail(error) {
//             console.error('逆地址解析失败:', error);
//           }
//         });
//       },
//       fail(err) {
//         console.error('getLocation 失败：', err);

//         // 判断是否是系统定位功能未开启
//         if (err.errMsg && err.errMsg.includes('LOCATIONSWITCHOFF')) {
//           uni.getSystemInfo({
//             success: (sys) => {
//               const isIOS = sys.platform === 'ios';

//               uni.showModal({
//                 title: '定位服务未开启',
//                 content: isIOS
//                   ? '检测到您的 iPhone 系统定位功能未开启，请前往“设置 → 隐私与安全性 → 定位服务”开启后重试。'
//                   : '检测到您的手机定位功能未开启，请前往“设置 → 位置服务”或下拉快捷开关中开启定位后重试。',
//                 confirmText: '我已开启',
//                 showCancel: false,
//                 success() {
//                   // 再次尝试定位（延迟避免 UI 闪烁）
//                   setTimeout(() => {
//                     tryGetLocation()
//                   }, 1000)
//                 }
//               })
//             },
//             fail() {
//               uni.showModal({
//                 title: '定位服务未开启',
//                 content: '检测到您的设备定位功能未开启，请在系统设置中开启定位后再试。',
//                 confirmText: '我已开启',
//                 showCancel: false,
//                 success() {
//                   setTimeout(() => {
//                     tryGetLocation()
//                   }, 1000)
//                 }
//               })
//             }
//           })
//         } else {
//           // 非系统定位问题，不循环
//           uni.showToast({
//             icon: 'none',
//             title: '定位失败，请检查网络和定位权限',
//           });
//         }
//       }
//     });
//   }

//   // 首先获取用户授权
//   uni.authorize({
//     scope: 'scope.userLocation',
//     success() {
//       tryGetLocation()
//     },
//     fail() {
//       console.log('用户未授权位置权限')
//       uni.showModal({
//         title: '权限请求',
//         content: '需要授权位置信息以使用定位功能，是否前往设置？',
//         confirmText: '去设置',
//         cancelText: '取消',
//         success(res) {
//           if (res.confirm) {
//             uni.openSetting()
//           }
//         }
//       })
//     }
//   })
// }
// 定位并获取地址
const getCurrentLocation = () => {
  console.log('开始获取当前位置')

  uni.getLocation({
    type: 'gcj02',
    success(res) {
      console.log('定位成功：', res)
      reverseGeocode(res.latitude, res.longitude)
    },
    fail(err) {
      console.error('定位失败:', err)
      const msg = err.errMsg || ''

      if (msg.includes('auth deny') || msg.includes('permission')) {
        // 用户拒绝授权
        uni.showModal({
          title: '定位权限未授权',
          content: '请前往小程序设置中手动开启“位置信息”权限。',
          confirmText: '去设置',
          showCancel: false,
          success(res) {
            if (res.confirm) {
              uni.openSetting({
                success(settingRes) {
                  if (settingRes.authSetting['scope.userLocation']) {
                    getCurrentLocation()
                  } else {
                    uni.showToast({ title: '未授权定位权限', icon: 'none' })
                  }
                },
              })
            }
          },
        })
      } else if (msg.includes('LOCATIONSWITCHOFF')) {
        // 系统级定位服务未开启（安卓/iOS 关闭了定位功能）
        uni.getSystemInfo({
          success(sys) {
            const isIOS = sys.platform === 'ios'
            uni.showModal({
              title: '定位服务未开启',
              content: isIOS
                ? 'iOS 系统定位未开启，请前往 设置 → 隐私与安全性 → 定位服务 开启后重试。'
                : '请前往 设置 → 位置信息 中开启定位后再试。',
              confirmText: '我已开启',
              showCancel: false,
              success() {
                setTimeout(() => {
                  getCurrentLocation()
                }, 1000)
              },
            })
          },
        })
      } else {
        uni.showToast({
          icon: 'none',
          title: '定位失败，请检查网络或系统设置',
        })
      }
    },
  })
}

// 腾讯地图逆地址解析
const reverseGeocode = (latitude, longitude) => {
  qqmapsdk.reverseGeocoder({
    location: { latitude, longitude },
    success(res) {
      console.log('逆地址解析成功：', res)
      const result = res.result
      formData.value.latitude = result.location.lat
      formData.value.longitude = result.location.lng
      formData.value.detailedLocation = result.address
      formData.value.location = result.formatted_addresses?.recommend || result.address
    },
    fail(err) {
      console.error('逆地址解析失败:', err)
      uni.showModal({
        title: '地址解析失败',
        content: JSON.stringify(err),
        showCancel: false,
      })
    },
  })
}

const openLocation = () => {
  uni.openLocation({
    latitude: 36.730529,
    longitude: 99.765019,
    name: '黑马河镇人民政府',
    address: '青海省海南藏族自治州共和县黑马河镇',
    success: function () {
      console.log('success')
    },
  })
}
// 开始/停止录音
const toggleRecord = () => {
  if (isRecording.value) {
    recorderManager.stop()
  } else {
    recorderManager.start({
      format: 'mp3',
      duration: 60000, // 最长60秒
    })
  }
}
// 录音开始
recorderManager.onStart(() => {
  isRecording.value = true
  toast.success('开始录音')
})
// 录音结束，自动上传
recorderManager.onStop(async (res) => {
  isRecording.value = false
  const { tempFilePath } = res
  if (!tempFilePath) {
    toast.error('录音失败')
    return
  }

  // 上传文件
  uni.uploadFile({
    url: uploadUrl,
    filePath: tempFilePath,
    name: 'file',
    header: headerObj.value,
    formData: {
      name: 'voice_' + Date.now() + '.mp3',
    },
    success: (uploadRes) => {
      try {
        const parsed = JSON.parse(uploadRes.data)
        if (parsed.code !== 0) {
          toast.error(parsed.msg || '录音上传失败')
          return
        }
        formData.value.record = parsed.url
        toast.success('录音上传成功')
      } catch (e) {
        toast.error('解析失败')
      }
    },
    fail: (err) => {
      console.error('上传失败', err)
      toast.error('上传失败')
    },
  })
})
</script>

<style scoped lang="scss">
.container {
  padding: 20px 5px;
}

.custom-shadow {
  width: 90%;
  font-size: 18px;
}

.submit-btn {
  background: red;
  color: white;
  border-radius: 40rpx;
  font-size: 32rpx;
  height: 88rpx;
  line-height: 88rpx;
  margin: 40rpx 24rpx;
}
</style>
